home *** CD-ROM | disk | FTP | other *** search
- ╒═══════════════════════════════╕
- │ W E L C O M E │
- │ To the VGA Trainer Program │ │
- │ By │ │
- │ DENTHOR of ASPHYXIA │ │ │
- │ (updated by Snowman) │ │ │
- ╘═══════════════════════════════╛ │ │
- ────────────────────────────────┘ │
- ────────────────────────────────┘
-
- --==[ PART 2 ]==--
-
-
-
- [Note: things in brackets have been added by Snowman. The original text
- has remained mostly unaltered except for the inclusion of C++ material]
-
- ■ Introduction
-
- Hi there again! This is Grant Smith, AKA Denthor of ASPHYXIA. This is the
- second part of my Training Program for new programmers. I have only had a
- lukewarm response to my first part of the trainer series ... remember, if
- I don't hear from you, I will assume that you are all dead and will stop
- writing the series ;-). Also, if you do get in contact with me I will give
- you some of our fast assembly routines which will speed up your demos no
- end. So go on, leave mail to GRANT SMITH in the main section of the
- MailBox BBS, start up a discussion or ask a few questions in this Conference,
- leave mail to ASPHYXIA on the ASPHYXIA BBS, leave mail to Denthor on
- Connectix, or write to Grant Smith,
- P.O.Box 270
- Kloof
- 3640
- See, there are many ways you can get in contact with me! Use one of them!
-
- In this part, I will put the Pallette through it's paces. What the hell is
- a pallette? How do I find out what it is? How do I set it? How do I stop
- the "fuzz" that appears on the screen when I change the pallette? How do
- I black out the screen using the pallette? How do I fade in a screen?
- How do I fade out a screen? Why are telephone calls so expensive?
- Most of these quesions will be answered in this, the second part of my
- Trainer Series for Pascal.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ What is the Pallette?
-
- A few weeks ago a friend of mine was playing a computer game. In the game
- there was a machine with stripes of blue running across it. When the
- machine was activated, while half of the the blue stripes stayed the same,
- the other half started to change color and glow. He asked me how two stripes
- of the same color suddenly become different like that. The answer is simple:
- the program was changing the pallette.
-
- As you know from Part 1, there are 256 colors in MCGA mode, numbered 0 to 255.
- What you don't know is that each if those colors is made up of different
- intensities of Red, Green and Blue, the primary colors (you should have
- learned about the primary colors at school). These intensities are numbers
- between 0 and 63. The color of bright red would for example be obtained by
- setting red intensity to 63, green intensity to 0, and blue intensity to 0.
- This means that two colors can look exactly the same, eg you can set color 10
- to bright red and color 78 to color bright red. If you draw a picture using
- both of those colors, no-one will be able to tell the difference between the
- two.. It is only when you again change the pallette of either of them will
- they be able to tell the difference.
-
- Also, by changing the whole pallette, you can obtain the "Fade in" and "Fade
- out" effects found in many demos and games. Pallette manipulation can become
- quite confusing to some people, because colors that look the same are in fact
- totally seperate.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I read in the pallette value of a color?
-
- This is very easy to do. To read in the pallette value, you enter in the
- number of the color you want into port $3c7 [0x03C7], then read in the values
- of red, green and blue respectively from port $3c9 [0x03C9]. Simple, huh? Here
- is a procedure that does it for you :
-
- [Pascal]
-
- Procedure GetPal(ColorNo : Byte; Var R,G,B : Byte);
- { This reads the values of the Red, Green and Blue values of a certain
- color and returns them to you. }
- Begin
- Port[$3c7] := ColorNo;
- R := Port[$3c9];
- G := Port[$3c9];
- B := Port[$3c9];
- End;
-
- [C++]
-
- void GetPal(unsigned char ColorNo, unsigned char &R,
- unsigned char &G, unsigned char &B) {
-
- outp (0x03C7,ColorNo); // here is the pallette color I want read
- R = inp (0x03C9);
- G = inp (0x03C9);
- B = inp (0x03C9);
-
- }
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I set the pallette value of a color?
-
- This is also as easy as 3.1415926535897932385. What you do is you enter in the
- number of the color you want to change into port $3c8 [0x03C8], then enter the
- values of red, green and blue respectively into port $3c9 [0x03C9]. Because
- you are all so lazy I have written the procedure for you ;-)
-
- [Pascal]
-
- Procedure Pal(ColorNo : Byte; R,G,B : Byte);
- { This sets the Red, Green and Blue values of a certain color }
- Begin
- Port[$3c8] := ColorNo;
- Port[$3c9] := R;
- Port[$3c9] := G;
- Port[$3c9] := B;
- End;
-
- [C++]
-
- void Pal(unsigned char ColorNo, unsigned char R,
- unsigned char G, unsigned char B) {
-
- outp (0x03C8,ColorNo); // here is the pallette color I want to set
- outp (0x03C9,R);
- outp (0x03C9,G);
- outp (0x03C9,B);
-
- }
-
- Asphyxia doesn't use the above pallete procedures, we use assembler versions,
- which will be given to PEOPLE WHO RESPOND TO THIS TRAINER SERIES (HINT,
- HINT)
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I stop the "fuzz" that appears on my screen when I change the
- pallette?
-
- If you have used the pallette before, you will have noticed that there is
- quite a bit of "fuzz" on the screen when you change it. The way we counter
- this is as follows : There is an elctron beam on your monitor that is
- constantly updating your screen from top to bottom. As it gets to the
- bottom of the screen, it takes a while for it to get back up to the top of
- the screen to start updating the screen again.
-
- The period where it moves from the bottom to the top is called the Verticle
- Retrace. During the verticle retrace you may change the pallette without
- affecting what is on the screen.
-
- What we do is that we wait until a verticle retrace has started by calling a
- certain procedure; this means that everything we do now will only be shown
- after the verticle retrace, so we can do all sorts of strange and unusual
- things to the screen during this retrace and only the results will be shown
- when the retrace is finished. This is way cool, as it means that when we
- change the pallette, the fuzz doesn't appear on the screen, only the result
- (the changed pallette), is seen after the retrace! Neat, huh? ;-) I have put
- the purely assembler WaitRetrace routine in the sample code that follows this
- message. Use it wisely, my son.
-
- NOTE : WaitRetrace can be a great help to your coding ... code that fits
- into one retrace will mean that the demo will run at the same
- speed no matter what your computer speed (unless you are doing a lot
- during the WaitRetrace and the computer is slooooow). Note that in
- the following sample program and in our SilkyDemo, the thing will run
- at the same speed whether turbo is on or off.
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I black out the screen using the pallette?
-
- This is basic : just set the Red, Green and Blue values of all colors to
- zero intensity, like so :
-
- [Pascal]
-
- Procedure Blackout;
- { This procedure blackens the screen by setting the pallette values of
- all the colors to zero. }
- VAR loop1:integer;
- BEGIN
- WaitRetrace;
- For loop1:=0 to 255 do
- Pal (loop1,0,0,0);
- END;
-
- [C++]
-
- void Blackout() {
-
- WaitRetrace();
- for (int loop1=0;loop1<256;loop1++)
- Pal (loop1,0,0,0);
-
- }
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I fade in a screen?
-
- Okay, this can be VERY effective. What you must first do is grab the
- pallette into a variable, like so :
-
- [Pascal] VAR Pall := Array [0.255,1..3] of BYTE;
- [C++] unsigned char Pall[256][3];
-
- 0 to 255 is for the 256 colors in MCGA mode, 1 to 3 is red, green and blue
- intensity values;
-
- [Pascal]
-
- Procedure GrabPallette;
- VAR loop1:integer;
- BEGIN
- For loop1:=0 to 255 do
- Getpal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);
- END;
-
- [C++]
-
- void GrabPallette() {
-
- for(int loop1=0;loop1<256;loop1++)
- GetPal(loop1,Pall2[loop1][0],Pall2[loop1][1],Pall2[loop1][2]);
-
- }
-
- This loads the entire pallette into variable pall. Then you must blackout
- the screen (see above), and draw what you want to screen without the
- construction being shown. Then what you do is go throgh the pallette. For
- each color, you see if the individual intensities are what they should be.
- If not, you increase them by one unit until they are. Beacuse intensites
- are in a range from 0 to 63, you only need do this a maximum of 64 times.
-
- [Pascal]
-
- Procedure Fadeup;
- VAR loop1,loop2:integer;
- Tmp : Array [1..3] of byte;
- { This is temporary storage for the values of a color }
- BEGIN
- For loop1:=1 to 64 do BEGIN
- { A color value for Red, green or blue is 0 to 63, so this loop only
- need be executed a maximum of 64 times }
- WaitRetrace;
- For loop2:=0 to 255 do BEGIN
- Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
- If Tmp[1]<Pall[loop2,1] then inc (Tmp[1]);
- If Tmp[2]<Pall[loop2,2] then inc (Tmp[2]);
- If Tmp[3]<Pall[loop2,3] then inc (Tmp[3]);
- { If the Red, Green or Blue values of color loop2 are less then they
- should be, increase them by one. }
- Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
- { Set the new, altered pallette color. }
- END;
- END;
- END;
-
- [C++]
-
- void Fadeup() {
-
- //This is temporary storage for the values of a color
- unsigned char Tmp[3];
-
- // A color value for Red, green or blue is 0 to 63, so this loop only
- // need be executed a maximum of 64 times.
- for(int loop1=0;loop1<64;loop1++) {
-
- WaitRetrace();
-
- for(int loop2=0; loop2<256; loop2++) {
- GetPal(loop2,Tmp[0],Tmp[1],Tmp[2]);
-
- // If the Red, Green or Blue values of color loop2 are less then they
- // should be, increase them by one.
- if ((Tmp[0] < Pall2[loop2][0]) && (Tmp[0] < 63)) Tmp[0]++;
- if ((Tmp[1] < Pall2[loop2][1]) && (Tmp[1] < 63)) Tmp[1]++;
- if ((Tmp[2] < Pall2[loop2][2]) && (Tmp[2] < 63)) Tmp[2]++;
-
- // Set the new, altered pallette color.
- Pal (loop2,Tmp[0],Tmp[1],Tmp[2]);
- }
- }
- }
-
- Hey-presto! The screen fades up. You can just add in a delay before the
- waitretrace if you feel it is too fast. Cool, no?
-
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ How do I fade out a screen?
-
- This is just like the fade in of a screen, just in the opposite direction.
- What you do is you check each color intensity. If it is not yet zero, you
- decrease it by one until it is. BAAASIIIC!
-
- [Pascal]
-
- Procedure FadeDown;
- VAR loop1,loop2:integer;
- Tmp : Array [1..3] of byte;
- { This is temporary storage for the values of a color }
- BEGIN
- For loop1:=1 to 64 do BEGIN
- WaitRetrace;
- For loop2:=0 to 255 do BEGIN
- Getpal (loop2,Tmp[1],Tmp[2],Tmp[3]);
- If Tmp[1]>0 then dec (Tmp[1]);
- If Tmp[2]>0 then dec (Tmp[2]);
- If Tmp[3]>0 then dec (Tmp[3]);
- { If the Red, Green or Blue values of color loop2 are not yet zero,
- then, decrease them by one. }
- Pal (loop2,Tmp[1],Tmp[2],Tmp[3]);
- { Set the new, altered pallette color. }
- END;
- END;
- END;
-
- [C++]
-
- void FadeDown() {
-
- // This is temporary storage for the values of a color
- unsigned char Tmp[3];
-
- for(int loop1=0; loop1<64; loop1++) {
-
- WaitRetrace();
-
- for(int loop2=0; loop2<256; loop2++) {
- GetPal(loop2,Tmp[0],Tmp[1],Tmp[2]);
-
- // If the Red, Green or Blue values of color loop2 are not yet zero,
- // then, decrease them by one.
- if (Tmp[0] > 0) Tmp[0]--;
- if (Tmp[1] > 0) Tmp[1]--;
- if (Tmp[2] > 0) Tmp[2]--;
-
- // Set the new, altered pallette color.
- Pal(loop2,Tmp[0],Tmp[1],Tmp[2]);
- }
- }
- }
-
- Again, to slow the above down, put in a delay above the WaitRetrace. Fading
- out the screen looks SO much more impressive then just clearing the screen;
- it can make a world of difference in the impression your demo etc will
- leave on the people viewing it. To restore the pallette, just do this :
-
- [Pascal]
-
- Procedure RestorePallette;
- VAR loop1:integer;
- BEGIN
- WaitRetrace;
- For loop1:=0 to 255 do
- pal (loop1,Pall[loop1,1],Pall[loop1,2],Pall[loop1,3]);
- END;
-
- [C++]
-
- void RestorePallette() {
-
- WaitRetrace();
- for(int loop1=0; loop1<255; loop1++)
- Pal(loop1,Pall2[loop1][0],Pall2[loop1][1],Pall2[loop1][2]);
-
- }
-
- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- ■ In closing
-
- Well, there are most of those origional questions answered ;-) The following
- sample program is quite big, so it might take you a while to get around it.
- Persevere and thou shalt overcome. Pallette manipulation has been a thorn
- in many coders sides for quite some time, yet hopefully I have shown you
- all how amazingly simple it is once you have grasped the basics.
-
- I need more feedback! In which direction would you like me to head? Is there
- any particular section you would like more info on? Also, upload me your
- demo's, however trivial they might seem. We really want to get in contact
- with/help out new and old coders alike, but you have to leave us that message
- telling us about yourself and what you have done or want to do.
-
- IS THERE ANYBODY OUT THERE!?!
-
- P.S. Our new demo should be out soon ... it is going to be GOOOD ... keep
- an eye out for it.
-
- [ And so she came across him, slumped over his keyboard
- yet again . 'It's three in the morning' she whispered.
- 'Let's get you to bed'. He stirred, his face bathed in
- the dull light of his monitor. He mutters something.
- As she leans across him to disconnect the power, she
- asks him; 'Was it worth it?'. His answer surprises her.
- 'No.' he says. In his caffiene-enduced haze, he smiles.
- 'But it sure is a great way to relax.' ]
- - Grant Smith
- Tue 13 July, 1993
- 2:23 am.
-
- See you next week!
- - Denthor
-
-